#include "MatrixUtility.h"
#include <iostream>


MatrixUtility::MatrixUtility(void)
{
}


MatrixUtility::~MatrixUtility(void)
{
}

//static method
float MatrixUtility::sum(cv::Mat_<float> A)
{
	
	float sum=0;	
	for(int i=0;i<A.rows;i++)
	{	
		for(int j=0;j<A.cols;j++)
		{	
			sum+=A(i,j);			
		}
	}
	
	return sum;
	
}

float MatrixUtility::mean(cv::Mat_<float> A)
{
	float s = sum(A);
	s/=(A.rows*A.cols);
	return s;
}

cv::Mat MatrixUtility::geq(cv::Mat_<float> A ,float v)
{
	cv::Mat result = cv::Mat::zeros(A.rows,A.cols,A.type());
	for(int i=0;i<A.rows;i++)
	{		
		for(int j=0;j<A.cols;j++)
		{			
			result.at<float>(i,j)=(A.at<float>(i,j)>=v?1:0);			
		}
	}

	return result;
}


cv::Mat MatrixUtility::ge(cv::Mat_<float> A ,float v)
{
	cv::Mat result = cv::Mat::zeros(A.rows,A.cols,A.type());
	for(int i=0;i<A.rows;i++)
	{		
		for(int j=0;j<A.cols;j++)
		{			
			result.at<float>(i,j)=(A.at<float>(i,j)>v?1:0);			
		}
	}

	return result;
}

cv::Mat MatrixUtility::le(cv::Mat_<float> A ,float v)
{
	cv::Mat result = cv::Mat::zeros(A.rows,A.cols,A.type());
	for(int i=0;i<A.rows;i++)
	{		
		for(int j=0;j<A.cols;j++)
		{			
			result.at<float>(i,j)=(A.at<float>(i,j)<v?1:0);			
		}
	}

	return result;
}

cv::Mat MatrixUtility::leq(cv::Mat_<float> A ,float v)
{
	cv::Mat result = cv::Mat::zeros(A.rows,A.cols,A.type());
	for(int i=0;i<A.rows;i++)
	{		
		for(int j=0;j<A.cols;j++)
		{			
			result.at<float>(i,j)=(A.at<float>(i,j)<=v?1:0);			
		}
	}

	return result;
}

cv::Mat MatrixUtility::eq(cv::Mat_<float> A ,float v)
{
	cv::Mat result = cv::Mat::zeros(A.rows,A.cols,A.type());
	for(int i=0;i<A.rows;i++)
	{		
		for(int j=0;j<A.cols;j++)
		{			
			result.at<float>(i,j)=(A.at<float>(i,j)==v?1:0);			
		}
	}

	return result;
}


cv::Vector<cv::Point> MatrixUtility::findGEQ(cv::Mat_<float> A ,float v)
{

	cv::Vector<cv::Point> result;
	for(int i=0;i<A.rows;i++)
	{		
		for(int j=0;j<A.cols;j++)
		{			
			if(A.at<float>(i,j)>=v)
			{
				result.push_back(cv::Point(i,j));
			}			
		}
	}

	return result;

}

cv::Vector<cv::Point> MatrixUtility::findLEQ(cv::Mat_<float> A ,float v)
{

	cv::Vector<cv::Point> result;
	for(int i=0;i<A.rows;i++)
	{		
		for(int j=0;j<A.cols;j++)
		{			
			if(A.at<float>(i,j)<=v)
			{
				result.push_back(cv::Point(i,j));
			}			
		}
	}

	return result;

}

cv::Vector<cv::Point> MatrixUtility::findEQ(cv::Mat_<float> A ,float v)
{

	cv::Vector<cv::Point> result;
	for(int i=0;i<A.rows;i++)
	{		
		for(int j=0;j<A.cols;j++)
		{			
			if(A.at<float>(i,j)==v)
			{
				result.push_back(cv::Point(i,j));
			}			
		}
	}

	return result;

}

cv::Vector<cv::Point> MatrixUtility::findLE(cv::Mat_<float> A ,float v)
{

	cv::Vector<cv::Point> result;
	for(int i=0;i<A.rows;i++)
	{		
		for(int j=0;j<A.cols;j++)
		{			
			if(A.at<float>(i,j)<v)
			{
				result.push_back(cv::Point(i,j));
			}			
		}
	}

	return result;

}

cv::Vector<cv::Point> MatrixUtility::findGE(cv::Mat_<float> A ,float v)
{

	cv::Vector<cv::Point> result;
	for(int i=0;i<A.rows;i++)
	{		
		for(int j=0;j<A.cols;j++)
		{			
			if(A.at<float>(i,j)>v)
			{
				result.push_back(cv::Point(i,j));
			}			
		}
	}

	return result;

}

cv::Mat MatrixUtility::pow(cv::Mat_<float> A ,int v)
{
	if(v<0)		return A;
	if(v==0)	return cv::Mat::ones(A.rows,A.cols,A.type());

	cv::Mat result;
	A.copyTo(result);
	for(int i=1;i<v;i++)
	{
		A=A.mul(A);
	}
	return A;
}